Playing Waveform-Audio Files

It s easy to play sounds in your application by using the functions, macros, and messages discussed in this overview. The techniques and elements documented here operate only on waveform audio; that is, digitized representations of a sound s physical shape. If you want to add music to your application, and you do not care about other kinds of sounds, you might want to use MIDI. For a discussion of a simple playback MIDI implementation, see the MCIWnd Window Class21TWU3C. For a discussion of the MIDI interface, see Musical Instrument Digital Interface (MIDI)Y1M7.7.

You can use the following functions to play waveform audio in your application in a single function call:

Function

Description

MessageBeep1FW785P

Plays the sound that corresponds to a specified system-alert level.

sndPlaySound12UD881

Plays the sound that corresponds to the system sound entered in the registry or the contents of the specified filename.

PlaySoundIMKKV6

Provides all the functionality of sndPlaySound12UD881 and can directly access resources.

 

The MessageBeep function is a standard part of the Win32 API; because its capabilities are very limited and it is documented elsewhere, it is not discussed here.

The functions listed provide the following methods of playing waveform audio:

    Playing waveform-audio files associated with system-alert levels

    Playing waveform-audio files specified by entries in the registry

    Playing in-memory WAVE resources

    Playing waveform-audio files stored on a hard disk or compact disc - read-only memory (CD-ROM)

 

The sndPlaySound12UD881 and PlaySoundIMKKV6 functions load an entire waveform-audio file into memory and, in effect, limit the size of file they can play. Use sndPlaySound and PlaySound to play waveform-audio files that are relatively small   up to about 100K. These two functions also require the sound data to be in a format that is playable by one of the installed waveform-audio drivers, including the wave mapper.

For larger sound files, use the Media Control Interface (MCI) services. For more information, see MCIYKB0V8.

Using Window Messages to Manage Waveform-Audio Playback

The following messages can be sent to a window procedure function for managing waveform-audio playback.

Message

Description

MM_WOM_CLOSE1QQ.D_N

Sent when the device is closed by using the waveOutClose11Z3QHJ function.

MM_WOM_DONEEE2C5P

Sent when the device driver is finished with a data block sent by using the waveOutWrite12C9KIJ function.

MM_WOM_OPENEE_CWY

Sent when the device is opened by using the waveOutOpen2MUO.P_ function.

 

A wParam and lParam parameter is associated with each of these messages. The wParam parameter always specifies a handle of the open waveform-audio device. For the MM_WOM_DONEEE2C5P message, lParam specifies a pointer to a WAVEHDR3CAL0JU structure that identifies the completed data block. The lParam parameter is unused for the MM_WOM_CLOSE1QQ.D_N and MM_WOM_OPENEE_CWY messages.

The most useful message is probably MM_WOM_DONE. When this message signals that playback of a data block is complete, you can clean up and free the data block. Unless you need to allocate memory or initialize variables, you probably do not need to process the MM_WOM_OPEN and MM_WOM_CLOSE messages.

The callback function for waveform-audio output devices is supplied by the application. For information about this callback function, see the waveOutProc4OFI_J7 function.

Retrieving the Current Playback Position

You can monitor the current playback position within the file while waveform audio is playing by using the waveOutGetPosition6GJJSW function.

For waveform-audio devices, samples are the preferred time format in which to represent the current position. Thus, the current position of a waveform-audio device is specified as the number of samples for one channel from the beginning of the waveform-audio file. To query the current position of a waveform-audio device, set the wType member of the MMTIMEM0484O structure to TIME_SAMPLES and pass this structure to waveOutGetPosition.

The MMTIME structure can represent time in one or more different formats, including milliseconds, samples, SMPTE (Society of Motion Picture and Television Engineers), and MIDI song pointer formats. The wType member specifies the format used to represent time. Before calling a function that uses the MMTIME structure, you must set wType to indicate your requested time format. Be sure to check wType after the call to see whether the requested time format is supported. If the requested time format is not supported, the device driver specifies the time in an alternate time format and changes the wType member to the selected time format.

For more information about the MMTIME structure, see Multimedia Timers12EALE7.

Stopping, Pausing, and Restarting Playback

You can stop or pause playback while waveform audio is playing. After playback has been paused, you can restart it. Windows provides the following functions for controlling waveform-audio playback.

Function

Description

waveOutPause1OE4W4Z

Pauses playback on a waveform-audio output device.

waveOutReset12_WU0Y

Stops playback on a waveform-audio output device and marks all pending data blocks as done.

WaveOutRestart.ZWYXM

Resumes playback on a paused waveform-audio output device.

 

Pausing a waveform-audio device by using waveOutPause1OE4W4Z might not be instantaneous; the driver may finish playing the current block before pausing playback.

Generally, as soon as the first waveform-audio data block is sent by using the waveOutWrite12C9KIJ function, the waveform-audio device begins playing. If you do not want the sound to start playing immediately, call waveOutPause before calling waveOutWrite. Then, when you want to begin playing waveform-audio data, call waveOutRestart.ZWYXM.

You cannot use waveOutRestart to restart a device that has been stopped with waveOutReset12_WU0Y; you must use waveOutWrite to send the first data block to resume playback on the device.

Looping Playback

Looping a sound is controlled by the dwLoops and dwFlags members in the WAVEHDR3CAL0JU structures passed to the device with the waveOutWrite12C9KIJ function. Use the WHDR_BEGINLOOP and WHDR_ENDLOOP flags in the dwFlags member to specify the beginning and ending data blocks for looping.

To loop a single data block, specify both flags for the same block. To specify the number of loops, use the dwLoops member in the WAVEHDR structure for the first block in the loop.

You can call the waveOutBreakLoop5GEIO6 function to stop a looping sound.

Changing the Volume of Waveform-Audio Playback

Windows provides the following functions to query and set the volume level of waveform-audio output devices.

Function

Description

waveOutGetVolume32JMIE

Retrieves the current volume level of the specified waveform-audio output device.

waveOutSetVolume1OPX_X7

Sets the volume level of the specified waveform-audio output device.

 

Not all waveform-audio devices support volume changes. Some devices support individual volume control on both the left and right channels. For information about how to determine the volume-control capabilities of waveform-audio devices, see Devices and Data Types1WTW_.O.

Some applications allow the user to control the volume for all audio devices in a system. (Many applications of this type use the audio mixer services; for more information, see Audio MixersGIF5BE.) Unless your application is capable of this kind of master volume control, you should open an audio device before changing its volume. You should also query the volume level before changing it and restore the volume level to its previous level as soon as possible.

Volume is specified in a doubleword value. When the audio format is stereo, the upper 16 bits specify the relative volume of the right channel and the lower 16 bits specify the relative volume of the left channel. For devices that do not support left- and right-channel volume control, the lower 16 bits specify the volume level, and the upper 16 bits are ignored.

Volume-level values range from 0x0 (silence) to 0xFFFF (maximum volume) and are interpreted logarithmically. The perceived volume increase is the same when increasing the volume level from 0x5000 to 0x6000 as it is from 0x4000 to 0x5000.

Changing Pitch and Playback Rate

Some waveform-audio output devices can vary the pitch and the playback rate of waveform-audio data. Not all waveform-audio devices support pitch and playback-rate changes. For information about how to determine whether a particular waveform-audio device supports pitch and playback rate changes, see Devices and Data Types1WTW_.O. 

The differences between changing pitch and playback rate are as follows:

    Changing the playback rate is performed by the device driver and does not require specialized hardware. The sample rate is not changed, but the driver interpolates by skipping or synthesizing samples. For example, if the playback rate is changed by a factor of two, the driver skips every other sample.

    Changing the pitch requires specialized hardware. The playback rate and sample rate are not changed.

 

Windows provides the following functions to query and set waveform-audio pitch and playback rates.

Function

Description

waveOutGetPitchM68QRT

Retrieves the pitch for the specified waveform-audio output device.

waveOutGetPlaybackRate1O82QGQ

Retrieves the playback rate for the specified waveform-audio output device.

waveOutSetPitch_6.TO2

Sets the pitch for the specified waveform-audio output device.

waveOutSetPlaybackRate2FFY_MF

Sets the playback rate for the specified waveform-audio output device.

 

The pitch and playback rates are changed by a factor specified with a fixed-point number packed into a doubleword value. The upper 16 bits specify the integer part of the number; the lower 16 bits specify the fractional part. For example, the value 1.5 is represented as 0x00018000L. The value 0.75 is represented as 0x0000C000L. A value of 1.0 (0x00010000) means the pitch or playback rate is unchanged.